package com.xtedu.examproject.controller;

import com.google.gson.Gson;
import com.xtedu.examproject.entity.Course;
import com.xtedu.examproject.entity.ExamQuestion;
import com.xtedu.examproject.entity.QuestionType;
import com.xtedu.examproject.entity.Result;
import com.xtedu.examproject.service.CourseService;
import com.xtedu.examproject.service.ExamQuestionRelaService;
import com.xtedu.examproject.service.ExamQuestionService;
import com.xtedu.examproject.service.QuestionTypeService;
import com.xtedu.examproject.util.CommonUtils;
import com.xtedu.examproject.util.PageHelper;
import com.xtedu.examproject.util.UploadUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.MultipartConfig;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/*
 * Author: xzy
 * Date: 2025/9/17
 * Last Modified by: xzy
 * Last Modified date: 2025/9/17
 * Description: TODO - Add file description here
 */
@WebServlet("/examquestionmanage/*")
@MultipartConfig(
        fileSizeThreshold = 1024 * 1024,      // 1MB - 内存中存储的最大文件大小
        maxFileSize = 1024 * 1024 * 10,       // 10MB - 单个文件最大大小
        maxRequestSize = 1024 * 1024 * 50     // 50MB - 整个请求的最大大小
)
public class ExamQuestionServlet extends HttpServlet {
    private ExamQuestionService examQuestionService;
    private static Gson gson;
    private static final int PAGE_SIZE = 10;
    private QuestionTypeService questionTypeService;
    private CourseService courseService;
    private ExamQuestionRelaService examQuestionRelaService;

    @Override
    public void init() throws ServletException {
        examQuestionService = new ExamQuestionService();
        questionTypeService = new QuestionTypeService();
        courseService = new CourseService();
        examQuestionRelaService = new ExamQuestionRelaService();
        gson = new Gson();
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String pathInfo = req.getPathInfo();

        // 处理 null 或空路径
        if (pathInfo == null || pathInfo.equals("/") || pathInfo.isEmpty()) {
            findAll(req, resp);
            return;
        }

        // 标准化路径（去除前导和尾随斜杠）
        String path = pathInfo.replaceAll("^/|/$", "");

        switch (path) {
            case "findById" -> findById(req, resp);
            case "findByType" -> findByType(req, resp);
            case "findByCourse" -> findByCourse(req, resp);
            case "findBySubject" -> findBySubject(req, resp);
            case "findAllCourse" -> findAllCourse(req, resp);
            case "findAllQuestionType" -> findAllQuestionType(req, resp);
            case "getQuestionTypeStats" -> getQuestionTypeStats(req, resp);
            case "findByQuestionType" -> findByQuestionType(req, resp);
            case "findByCourseAndType" -> findByCourseAndType(req, resp);
            case "search" -> search(req, resp);
            default -> findAll(req, resp);
        }
    }

    private void findBySubject(HttpServletRequest req, HttpServletResponse resp) {
    }

    private void findByCourse(HttpServletRequest req, HttpServletResponse resp) {


    }

    /**
     * 获取各题型的统计信息
     *
     * @param req
     * @param resp
     * @throws IOException
     */
    private void getQuestionTypeStats(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        try {
            // 获取各题型的统计信息
            List<Map<String, Object>> stats = examQuestionService.getQuestionTypeStats();
            CommonUtils.sendSuccessResponse(resp, "查询成功", stats);
        } catch (Exception e) {
            CommonUtils.sendErrorResponse(resp, "查询失败: " + e.getMessage());
        }
    }

    /**
     * 获取到所有课程
     *
     * @param req
     * @param resp
     * @throws IOException
     */
    private void findAllCourse(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        try {
            List<Course> courses = courseService.findAllCourse();
            CommonUtils.sendSuccessResponse(resp, "查询成功", courses);
        } catch (Exception e) {
            CommonUtils.sendErrorResponse(resp, "查询失败: " + e.getMessage());
        }
    }

    /**
     * 获取所有题型类型
     *
     * @param req
     * @param resp
     * @throws IOException
     */
    private void findAllQuestionType(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        try {
            List<QuestionType> questionTypes = questionTypeService.findAllQuestionType();
            CommonUtils.sendSuccessResponse(resp, "查询成功", questionTypes);
        } catch (Exception e) {
            CommonUtils.sendErrorResponse(resp, "查询失败: " + e.getMessage());
        }
    }

    /**
     * 按题型查询
     */
    private void findByType(HttpServletRequest req, HttpServletResponse resp) {
        // 获取当前页码
        int pageIndex = req.getParameter("pageIndex") == null ? 1 : Integer.parseInt(req.getParameter("pageIndex"));
        int questionTypeId = Integer.parseInt(req.getParameter("questionTypeId"));

        try {
            PageHelper page = examQuestionService.findPageByType(questionTypeId, pageIndex, PAGE_SIZE);
            if (page == null || page.getItems().isEmpty() || page.getTotalCount() == 0) {
                req.setAttribute("code", "500");
                req.setAttribute("message", "按题型未查到数据");
                req.getRequestDispatcher("/WEB-INF/views/questionStore.jsp").forward(req, resp);
                return;
            }

            if (page != null) {
                String servletName = req.getPathInfo() == null ? req.getServletPath() : req.getServletPath() + req.getPathInfo();
                page.setServletName(servletName);
            }

            req.setAttribute("page", page);
            req.getRequestDispatcher("/WEB-INF/views/questionStore.jsp").forward(req, resp);
        } catch (ServletException | IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 根据题型查询题目
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    private void findByQuestionType(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 获取当前页码
        int pageIndex = req.getParameter("pageIndex") == null ? 1 : Integer.parseInt(req.getParameter("pageIndex"));
        int questionTypeId = Integer.parseInt(req.getParameter("questionTypeId"));

        try {
            PageHelper page = examQuestionService.findPageByType(questionTypeId, pageIndex, PAGE_SIZE);
            if (page == null || page.getItems().isEmpty() || page.getTotalCount() == 0) {
                CommonUtils.sendErrorResponse(resp, "按题型未查到数据");
                return;
            }

            // 注意：这里应该返回 page.getItems() 而不是整个 page 对象
            CommonUtils.sendSuccessResponse(resp, "查询成功", page.getItems());
        } catch (Exception e) {
            CommonUtils.sendErrorResponse(resp, "查询失败: " + e.getMessage());
        }
    }

    /**
     * 根据课程和题型查询题目
     *
     * @param req
     * @param resp
     * @throws IOException
     */
    private void findByCourseAndType(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        try {
            // 获取参数
            String courseIdParam = req.getParameter("courseId");
            String questionTypeIdParam = req.getParameter("questionTypeId");
            String pageIndexParam = req.getParameter("pageIndex");

            // 参数处理
            Integer courseId = null;
            Integer questionTypeId = null;
            int pageIndex = pageIndexParam == null ? 1 : Integer.parseInt(pageIndexParam);

            if (courseIdParam != null && !courseIdParam.isEmpty()) {
                courseId = Integer.parseInt(courseIdParam);
            }

            if (questionTypeIdParam != null && !questionTypeIdParam.isEmpty()) {
                questionTypeId = Integer.parseInt(questionTypeIdParam);
            }

            // 调用service方法查询数据
            PageHelper page = examQuestionService.findPageByCourseAndType(courseId, questionTypeId, pageIndex, PAGE_SIZE);

            // 处理查询结果
            if (page == null || page.getItems().isEmpty() || page.getTotalCount() == 0) {
                CommonUtils.sendErrorResponse(resp, "未查到符合条件的数据");
                return;
            }

            // 返回成功响应
            CommonUtils.sendSuccessResponse(resp, "查询成功", page.getItems());
        } catch (NumberFormatException e) {
            CommonUtils.sendErrorResponse(resp, "参数格式错误: " + e.getMessage());
        } catch (Exception e) {
            CommonUtils.sendErrorResponse(resp, "查询失败: " + e.getMessage());
        }
    }

    /**
     * 搜索题目
     */
    private void search(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取搜索参数
        String courseIdParam = req.getParameter("courseId");
        String questionTypeIdParam = req.getParameter("questionTypeId");
        String searchText = req.getParameter("searchText");
        String pageIndexParam = req.getParameter("pageIndex");

        int pageIndex = pageIndexParam == null ? 1 : Integer.parseInt(pageIndexParam);

        try {
            PageHelper page;

            // 根据不同条件调用不同的搜索方法
            if ((courseIdParam != null && !courseIdParam.isEmpty()) ||
                    (questionTypeIdParam != null && !questionTypeIdParam.isEmpty()) ||
                    (searchText != null && !searchText.isEmpty())) {

                Integer courseId = null;
                Integer questionTypeId = null;

                if (courseIdParam != null && !courseIdParam.isEmpty()) {
                    courseId = Integer.parseInt(courseIdParam);
                }

                if (questionTypeIdParam != null && !questionTypeIdParam.isEmpty()) {
                    questionTypeId = Integer.parseInt(questionTypeIdParam);
                }

                // 这里需要在 ExamQuestionService 中添加相应的搜索方法
                page = examQuestionService.searchQuestions(courseId, questionTypeId, searchText, pageIndex, PAGE_SIZE);
            } else {
                // 如果没有搜索条件，显示所有题目
                page = examQuestionService.findAllByPage(pageIndex, PAGE_SIZE);
            }

            if (page == null || page.getItems().isEmpty() || page.getTotalCount() == 0) {
                req.setAttribute("code", "500");
                req.setAttribute("message", "未查到符合条件的数据");
            } else {
                req.setAttribute("page", page);
            }

            // 传递搜索条件到页面，用于保持筛选状态
            req.setAttribute("searchCourseId", courseIdParam);
            req.setAttribute("searchQuestionTypeId", questionTypeIdParam);
            req.setAttribute("searchText", searchText);

            String servletName = req.getServletPath() + "/search";
            page.setServletName(servletName);

            req.getRequestDispatcher("/WEB-INF/views/questionStore.jsp").forward(req, resp);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String pathInfo = req.getPathInfo();

        // 标准化路径（去除前导和尾随斜杠）
        String path = pathInfo.replaceAll("^/|/$", "");

        switch (path) {
            case "add" -> add(req, resp);
            case "update" -> update(req, resp);
            case "delete" -> delete(req, resp);
            case "upload" -> UploadUtil.uploadFile(req, resp);
            case "deleteBatch" -> deleteBatch(req, resp);
        }
    }

    private void deleteBatch(HttpServletRequest req, HttpServletResponse resp) {
        try {
            // 通过多个同名参数接收
            String[] idStrings = req.getParameterValues("questionIds[]");
            if (idStrings == null || idStrings.length == 0) {
                CommonUtils.sendErrorResponse(resp, "未选择要删除的题目");
                return;
            }

            // 先筛选出可以删除的题目
            List<Integer> validQuestionIds = new ArrayList<>();
            List<String> errorMessages = new ArrayList<>();
            // 不允许删除所有未开考和考试中的试卷中的题目
            for (String idStr : idStrings) {
                int id = Integer.parseInt(idStr);
                if (examQuestionService.isNotInEndExam(id)) {
                    errorMessages.add("\n" + "题目" + id + "正在考试中，请勿删除");
                } else {
                    validQuestionIds.add(id);
                }
            }

            // 删除存在于所有已考完的试卷中的题目
            // 1. 先查询有效数组中存在于已考完考试试卷中的题目，id数组返回
            List<Integer> endQuestionIds = examQuestionRelaService.findEndingExamQuestionIds(validQuestionIds);
            // 2. 批量删除exam_question表中的题目
            int[] deleted = examQuestionRelaService.deleteBatch(endQuestionIds);
            if (deleted.length != endQuestionIds.size()) {
                errorMessages.add("试卷（exam_question）中题目" + (endQuestionIds.size() - deleted.length) + "删除失败");
            }

            // 处理批量删除逻辑
            int[] deleteCounts = examQuestionService.deleteBatch(validQuestionIds);
            if (deleteCounts.length != validQuestionIds.size()) {
                CommonUtils.sendErrorResponse(resp, (validQuestionIds.size() - deleteCounts.length) + "条数据删除失败" + errorMessages);
                return;
            }
            CommonUtils.sendSuccessResponse(resp, "成功删除" + deleteCounts.length + " 条数据" + (errorMessages == null ? "" : "。" + errorMessages));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private void add(HttpServletRequest req, HttpServletResponse resp) {
        try {
            ExamQuestion examQuestion = CommonUtils.getFormDataFromRequest(req, ExamQuestion.class);
            if (examQuestionService.insert(examQuestion) <= 0) {
                CommonUtils.sendErrorResponse(resp, "添加失败");
            }
            CommonUtils.sendSuccessResponse(resp, "添加成功");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void update(HttpServletRequest req, HttpServletResponse resp) {
        Result result = null;
        try {
            ExamQuestion examQuestion = CommonUtils.getFormDataFromRequest(req, ExamQuestion.class);
            if (examQuestionService.update(examQuestion) == 0) {
                result = new Result(0, "更新失败", null);
            } else {
                result = new Result(1, "更新成功", null);
            }
            String json = gson.toJson(result);
            resp.getWriter().println(json);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private void delete(HttpServletRequest req, HttpServletResponse resp) {
        Result result = null;
        try {
            int id = Integer.parseInt(req.getParameter("questionId"));
            if (examQuestionService.deleteById(id) == 0) {
                result = new Result(0, "删除失败", null);
            } else {
                result = new Result(1, "删除成功", null);
            }
            String json = gson.toJson(result);
            resp.getWriter().println(json);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private void findById(HttpServletRequest req, HttpServletResponse resp) {
        try {
            int id = Integer.parseInt(req.getParameter("questionId"));
            ExamQuestion examQuestion = examQuestionService.findById(id);
            if (examQuestion == null) {
                CommonUtils.sendErrorResponse(resp, "题库数据获取失败");
                return;
            }
            CommonUtils.sendSuccessResponse(resp, "题库数据获取成功", examQuestion);
        } catch (Exception e) {
            throw new RuntimeException("参数格式错误", e); // 让全局异常处理器处理
        }
    }

    private void findAll(HttpServletRequest req, HttpServletResponse resp) {
        // 获取当前页码
        int pageIndex = req.getParameter("pageIndex") == null ? 1 : Integer.parseInt(req.getParameter("pageIndex"));

        Result result = null;
        try {
            PageHelper page = examQuestionService.findAllByPage(pageIndex, PAGE_SIZE);
            if (page == null || page.getItems().isEmpty() || page.getTotalCount() == 0) {
                req.setAttribute("code", "500");
                req.setAttribute("message", "题库无数据或未完成初始化");
                req.getRequestDispatcher("/WEB-INF/views/questionStore.jsp").forward(req, resp);
                return;
            }

            if (page != null) {
                String servletName = req.getPathInfo() == null ? req.getServletPath() : req.getServletPath() + req.getPathInfo();
                page.setServletName(servletName);
            }

            req.setAttribute("page", page);
            req.getRequestDispatcher("/WEB-INF/views/questionStore.jsp").forward(req, resp);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    @Override
    public void destroy() {
    }
}
